HAL LTDC Typical use cases for migration

This section provides information about the HAL LTDC Typical use cases for migration.

LTDC configuration and start display

In HAL1, to display an image on the LCD, the HAL_LTDC_Init() function must be called to initialize the HAL LTDC driver and handle, configure the LTDC peripheral according to the screen parameters, enable interrupts, and start the LTDC. HAL_LTDC_ConfigLayer() is then called to configure the layer and immediately reloads the configuration.

In HAL2, the process begins with HAL_LTDC_Init() to initialize the HAL LTDC driver and handle, then HAL_LTDC_SetConfig() to configure the LTDC peripheral according to the screen parameters, and HAL_LTDC_Start() to enable interrupts and start the LTDC. Then the layer configuration is performed by calling HAL_LTDC_SetConfigLayer(). The reload operation is no longer integrated within HAL_LTDC_SetConfigLayer(), it is then necessary to explicitly call HAL_LTDC_ForceReload() to apply the updated settings.

Sequence diagram

HAL1

HAL2

@startuml
== LTDC Initialization and Configuration==
"Application" -> "LTDC" : HAL_LTDC_Init()
"LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM
"Application" -> "System" : LTDC HW Initialization
"System" --> "Application" :

== LTDC Layer Configuration ==
"Application" -> "LTDC" : HAL_LTDC_ConfigLayer()
"LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM

@enduml

@startuml
== Initialization ==
"Application" -> "LTDC" : HAL_LTDC_Init()
"LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM
"Application" -> "System" : LTDC HW Initialization
"System" --> "Application" :

== LTDC Configuration ==
"Application" -> "LTDC" : HAL_LTDC_SetConfig()
"LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM
"Application" -> "LTDC" : HAL_LTDC_Start()
"LTDC" --> "Application" : HAL_OK

== LTDC Layer Configuration ==
"Application" -> "LTDC" : HAL_LTDC_SetConfigLayer()
"LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM
"Application" -> "LTDC" : HAL_LTDC_ForceReload()
"LTDC" --> "Application" :

@enduml

Code snippet

HAL1

HAL2

LTDC_HandleTypeDef hltdc;






/*LTDC configuration */
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync     = 3;
hltdc.Init.VerticalSync       = 3;
hltdc.Init.AccumulatedHBP     = 11;
hltdc.Init.AccumulatedVBP     = 11;
hltdc.Init.AccumulatedActiveW = 811;
hltdc.Init.AccumulatedActiveH = 491;
hltdc.Init.TotalWidth         = 819;
hltdc.Init.TotalHeigh         = 499;
hltdc.Init.Backcolor.Blue     = 0;
hltdc.Init.Backcolor.Green    = 0;
hltdc.Init.Backcolor.Red      = 0;



HAL_LTDC_Init(&hltdc);


LTDC_LayerCfgTypeDef pLayerCfg = {0};

/*LTDC layer configuration */
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 485;
pLayerCfg.WindowY0 = 100;
pLayerCfg.WindowY1 = 330;
pLayerCfg.PixelFormat     = LTDC_PIXEL_FORMAT_ARGB4444;
pLayerCfg.FBStartAdress   = 0x00;
pLayerCfg.ImageWidth      = 480;
pLayerCfg.ImageHeight     = 272;
pLayerCfg.Alpha           = 255;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
pLayerCfg.Alpha0          = 0;
pLayerCfg.Backcolor.Blue  = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red   = 0;

HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0);
hal_ltdc_handle_t  hltdc;

/* LTDC initialization */
HAL_LTDC_Init(&hltdc, HAL_LTDC);

hal_ltdc_config_t ltdc_cfg;

/*LTDC configuration */
ltdc_cfg.hsync_polarity       = HAL_LTDC_HSYNC_POLARITY_LOW;
ltdc_cfg.vsync_polarity       = HAL_LTDC_VSYNC_POLARITY_LOW;
ltdc_cfg.data_enable_polarity = HAL_LTDC_DATA_ENABLE_POLARITY_LOW;
ltdc_cfg.pixel_clock_polarity = HAL_LTDC_PIXEL_CLOCK_POLARITY_LOW;
ltdc_cfg.hsync           = 3;
ltdc_cfg.vsync           = 3;
ltdc_cfg.h_back_porch    = 11;
ltdc_cfg.v_back_porch    = 11;
ltdc_cfg.active_width    = 811;
ltdc_cfg.active_height   = 491;
ltdc_cfg.h_front_porch   = 819;
ltdc_cfg.v_front_porch   = 499;
/* No need to configure the background color as the default value 0x000000
corresponds to the reset value. if needed you can use the function
HAL_LTDC_SetBackgroundColor(const hal_ltdc_handle_t *hltdc, uint32_t rgb888_color)
to configure the background color. */


HAL_LTDC_SetConfig(&hltdc, &ltdc_cfg);
HAL_LTDC_Start(&hltdc,HAL_LTDC_IT_NONE);

hal_ltdc_layer_config_t layer_cfg;

/*LTDC layer configuration */
layer_cfg.window_x0 = 0;
layer_cfg.window_x1 = 485;
layer_cfg.window_y0 = 100;
layer_cfg.window_y1 = 330;
layer_cfg.frame_buffer.pixel_format = HAL_LTDC_PIXEL_FORMAT_ARGB4444;
layer_cfg.frame_buffer.address      = 0x00;
layer_cfg.frame_buffer.width        = 480;
layer_cfg.frame_buffer.height       = 272;
layer_cfg.alpha                     = 255;
layer_cfg.blending_factor1          = HAL_LTDC_BLENDING_FACTOR1_CA;
layer_cfg.blending_factor2          = HAL_LTDC_BLENDING_FACTOR2_1_MINUS_CA;
layer_cfg.background_color_argb8888 = 0x00;




HAL_LTDC_SetConfigLayer(&hltdc, HAL_LTDC_LAYER_1, &layer_cfg);
HAL_LTDC_ForceReload(&hltdc, HAL_LTDC_RELOAD_IMMEDIATE);

LTDC update display frame buffer

To display an image and then update the frame buffer with a new image:

  • In HAL1, use HAL_LTDC_ConfigLayer() to display the first image, this function triggers an immediate forced reload. To update the frame buffer, HAL_LTDC_ConfigLayer() should be re-called causing a flickering on the screen due to the immediate reload. To prevent this flicker, the recommended approach is to use HAL_LTDC_ConfigLayer_NoReload(), which updates the layer configuration, then perform a reload during the vertical blanking period by calling HAL_LTDC_Reload().

  • In HAL2, use HAL_LTDC_ConfigLayer() to display the first image, followed by HAL_LTDC_ForceReload(), since the configuration function no longer triggers an automatic reload. To update the frame buffer, call HAL_LTDC_SetLayerFrameBuffer() followed by a vertical blanking reload to smoothly update the display without flicker.

Sequence diagram

HAL1

HAL2

@startuml
== Initialization and Configuration ==

== LTDC Layer Configuration ==
"Application" -> "LTDC" : HAL_LTDC_ConfigLayer()
"LTDC" --> "Application" :

== LTDC change Layer frame buffer ==
"Application" -> "LTDC" : HAL_LTDC_ConfigLayer_NoReload()
"LTDC" --> "Application" :
"Application" -> "LTDC" : HAL_LTDC_Reload()
 "LTDC" --> "Application" :
note right : The image updates smoothly as\n it is displayed in the\n next frame following the vertical\n blanking reload.

@enduml

@startuml
== Initialization and Configuration ==

== LTDC Layer Configuration ==
 "Application" -> "LTDC" : HAL_LTDC_SetConfigLayer()
 "LTDC" --> "Application" : HAL_OK or HAL_INVALID_PARAM
 "Application" -> "LTDC" : HAL_LTDC_ForceReload()
 "LTDC" --> "Application" :

== LTDC change Layer frame buffer ==
group #LightYellow Optional
"Application" -> "LTDC" : HAL_LTDC_SetLayerFrameBuffer()
"LTDC" --> "Application" :
end

"Application" -> "LTDC" : HAL_LTDC_ForceReload()
 "LTDC" --> "Application" :
 note right : The image updates smoothly as\n it is displayed in the\n next frame following the vertical\n blanking reload.

@enduml

Code snippet

HAL1

HAL2

LTDC_HandleTypeDef hltdc;

/* Initialize and configure the LTDC */

LTDC_LayerCfgTypeDef pLayerCfg = {0};


/*LTDC layer configuration */
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 480;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 272;
pLayerCfg.PixelFormat     = LTDC_PIXEL_FORMAT_ARGB4444;
pLayerCfg.FBStartAdress   = (uint32_t)&ARGB4444_480x272;
pLayerCfg.ImageWidth      = 480;
pLayerCfg.ImageHeight     = 272;
pLayerCfg.Alpha           = 255;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
pLayerCfg.Alpha0          = 0;
pLayerCfg.Backcolor.Blue  = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red   = 0;

HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0);


/* Update the frame buffer */
pLayerCfg.PixelFormat     = LTDC_PIXEL_FORMAT_ARGB1555;
pLayerCfg.FBStartAdress   = (uint32_t)&test_pattern_240x320_1555;
pLayerCfg.ImageWidth      = 240;
pLayerCfg.ImageHeight     = 320;

HAL_LTDC_ConfigLayer_NoReload(&hltdc, &pLayerCfg, 0);
HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING);
hal_ltdc_handle_t  hltdc;

/* Initialize and configure the LTDC */

hal_ltdc_layer_config_t layer_cfg;
hal_ltdc_frame_buffer_t frame_buffer_cfg;

/*LTDC layer configuration */
layer_cfg.window_x0 = 0;
layer_cfg.window_x1 = 480;
layer_cfg.window_y0 = 0;
layer_cfg.window_y1 = 272;
layer_cfg.frame_buffer.pixel_format = HAL_LTDC_PIXEL_FORMAT_ARGB4444;
layer_cfg.frame_buffer.address      = (uint32_t)&ARGB4444_480x272;
layer_cfg.frame_buffer.width        = 480;
layer_cfg.frame_buffer.height       = 272;
layer_cfg.alpha                     = 255;
layer_cfg.blending_factor1          = HAL_LTDC_BLENDING_FACTOR1_CA;
layer_cfg.blending_factor2          = HAL_LTDC_BLENDING_FACTOR2_1_MINUS_CA;
layer_cfg.background_color_argb8888 = 0;




HAL_LTDC_SetConfigLayer(&hltdc, HAL_LTDC_LAYER_1, &layer_cfg);
HAL_LTDC_ForceReload(&hltdc, HAL_LTDC_RELOAD_IMMEDIATE);

/* Update the frame buffer */
frame_buffer_cfg.pixel_format = HAL_LTDC_PIXEL_FORMAT_ARGB1555;
frame_buffer_cfg.address      = (uint32_t)&test_pattern_240x320_1555;
frame_buffer_cfg.width        = 240;
frame_buffer_cfg.height       = 320;

HAL_LTDC_SetLayerFrameBuffer(&hltdc, HAL_LTDC_LAYER_1, &frame_buffer_cfg);
HAL_LTDC_ForceReload(&hltdc, HAL_LTDC_RELOAD_VERTICAL_BLANKING);